import React, {MouseEvent} from 'react';
import "./item.css";
import {CloseOutlined, EditOutlined, InfoCircleOutlined, MinusCircleOutlined, PlusOutlined,} from "@ant-design/icons";
import {AutoComplete, AutoCompleteProps, Button, Collapse, Input, Select, Tooltip} from "antd";

export const POINTER_SIZE = 20;
const Types = {
    string: 'string',
    number: 'number',
    boolean: 'boolean',
    object: 'object',
    array: 'array',
}

export interface FlowItemParams {
    name: string,
    type: 'object' | 'array' | 'string' | 'number' | 'boolean',
    value: any,
    desc?: string,
}

interface FlowItemProps {
    inputs: FlowItemParams[];
    outputs: FlowItemParams[];
    title: string;
    description: string;
    style?: React.CSSProperties;
    active?: boolean;
    editable?: boolean;
    inCount: number;
    outCount: number;
    onPointerClick: (e: MouseEvent, isInput: boolean, index: number) => void;
    onPointerMove: (e: MouseEvent, isInput: boolean, index: number) => void;
    handleValueSelect: (value: string, type: string) => any[];
    onClick?: (e: MouseEvent) => void;
    onMouseDown?: (e: MouseEvent) => void;
    handleRef?: (ref: HTMLDivElement) => void;
    OnInputChange?: (inputs: FlowItemParams[]) => void;
    OnOutputChange?: (outputs: FlowItemParams[]) => void;
    OnTitleChange?: (title: string) => void;
    OnDelete?: () => void;
    pointerRef?: (ref: HTMLElement, isInput: boolean, index: number) => void;

}


export class FlowItem extends React.Component<FlowItemProps, any> {

    container: HTMLDivElement | null = null
    state: {
        titleEdit: boolean,
        inputOptions: { [key: string]: AutoCompleteProps['options'] }
    } = {
        titleEdit: false,
        inputOptions: {}
    }

    constructor(props: FlowItemProps) {
        super(props);
        this.ref = this.ref.bind(this)
        this.renderInput = this.renderInput.bind(this)
    }

    componentDidMount() {
        if (!this.container) {
            return
        }
        // console.log("container.clientHeight:", this.container.clientHeight)

    }

    componentWillUnmount() {

    }

    ref(ref: HTMLDivElement) {
        this.props.handleRef?.(ref);
        this.container = ref

    }

    renderInput(item: FlowItemParams, index: number) {
        return <AutoComplete size={"small"} value={item.value}
                             style={{width: "100%"}}
                             options={this.state.inputOptions[item.name]}
                             onSearch={(text) => {
                                 if (text && text.startsWith("$")) {
                                     const a = this.props.handleValueSelect(text, item.type);
                                     this.state.inputOptions[item.name] = a.map(v => ({value: v}))
                                 } else {
                                     this.state.inputOptions[item.name] = undefined
                                 }

                                 this.setState({
                                     inputOptions: {
                                         ...this.state.inputOptions
                                     }
                                 })
                             }}
                             onChange={(e) => {
                                 item.value = e
                                 this.setState({})
                                 this.props.OnInputChange?.([...this.props.inputs])
                             }} onClick={(e) => {
            // @ts-ignore
            e.target.focus()
            e.stopPropagation()
        }}/>
    }

    render() {

        return (

            <div
                className={`flow-item ${this.props.active ? 'active' : ''}`}
                onClick={this.props.onClick}
                onMouseDown={this.props.onMouseDown}
                ref={this.ref}
                style={this.props.style}>
                <div className={"flow-item-head"}>
                    <div className={"flow-item-title"}>
                        <p className={"flow-item-title-text"}
                           style={{display: this.state.titleEdit ? 'none' : 'block'}}>
                            <span>{this.props.title}<EditOutlined className={"edit-icon"} onClick={e => {
                                this.setState({titleEdit: true})
                            }}/></span>
                        </p>
                        <p className={"flow-item-title-edit"}
                           style={{display: this.state.titleEdit ? 'block' : 'none'}}>
                            <Input
                                value={this.props.title}
                                onBlur={e => {
                                    this.setState({titleEdit: false})
                                }}
                                onPressEnter={e => {
                                    this.setState({titleEdit: false})
                                }}
                                onChange={(e) => {
                                    this.props.OnTitleChange?.(e.target.value)
                                }}/>
                        </p>
                        <div className={"flow-item-title-menu"}>
                            <CloseOutlined className={"delete"} onClick={e => {
                                this.props.OnDelete?.()
                                e.stopPropagation()
                            }}/>
                        </div>
                    </div>
                    <div className={"description"}>
                        <span>{this.props.description}</span>
                    </div>
                </div>
                < >
                    {
                        Array(this.props.inCount).fill(0).map((_, index) => {
                            return <span key={index}
                                         className={"flow-item-pointer pointer-in"}
                                         style={{
                                             top: `${(index + 1) * 100 / (this.props.inCount + 1)}%`
                                         }}
                                         ref={(ref) => {
                                             if (!ref) {
                                                 return
                                             }
                                             this.props.pointerRef?.(ref, true, index)
                                         }}
                                         onMouseMove={(e) => this.props.onPointerMove(e, true, index)}
                                         onMouseDown={(e) => this.props.onPointerClick(e, true, index)}
                            >
                                <div
                                    className={"item-pointer-c"}

                                ></div>
                            </span>
                        })
                    }
                    {
                        Array(this.props.outCount).fill(0).map((_, index) => {
                            return <span key={index} className={"flow-item-pointer pointer-out"}
                                         style={{
                                             top: `${(index + 1) * 100 / (this.props.outCount + 1)}%`
                                         }}
                                         ref={(ref) => {
                                             if (!ref) {
                                                 return
                                             }
                                             this.props.pointerRef?.(ref, false, index)
                                         }}
                                         onMouseMove={(e) => this.props.onPointerMove(e, false, index)}
                                         onMouseDown={(e) => this.props.onPointerClick(e, false, index)}>
                                 <div
                                     className={"item-pointer-c"}
                                 ></div>
                            </span>
                        })
                    }
                </>
                <Collapse
                    className={"flow-item-body flow-item-input"}
                    size="small"
                    bordered={false}
                    items={
                        [{
                            key: '1',
                            label: '输入',
                            children: <>
                                <table className='detail-table detail-table-input'>
                                    <tbody>
                                    <tr key={0}>
                                        <td className='tdTitle' style={{width: '30%'}}>参数名</td>
                                        <td className='tdTitle' style={{width: '20%'}}>类型</td>
                                        <td className='tdTitle' style={{width: '45%'}}>参数值</td>
                                        <td className='tdTitle' style={{width: '5%'}}></td>
                                    </tr>
                                    {
                                        this.props.inputs.map((item, index) => {
                                            if (this.props.editable) {
                                                return <tr key={index}>
                                                    <td><Input size={"small"} value={item.name} onChange={(e) => {
                                                        item.name = e.target.value
                                                        this.setState({})
                                                        this.props.OnInputChange?.([...this.props.inputs])
                                                    }} onClick={(e) => {
                                                        // @ts-ignore
                                                        e.target.focus()
                                                        e.stopPropagation()
                                                    }}/></td>
                                                    <td><Select size={"small"} popupMatchSelectWidth={120}
                                                                value={item.type} onChange={(e) => {
                                                        item.type = e
                                                        this.props.OnInputChange?.(this.props.inputs)
                                                    }}>
                                                        {Object.keys(Types).map((type) => {
                                                            return <Select.Option
                                                                key={type}
                                                                value={type}>{type}</Select.Option>
                                                        })}
                                                    </Select></td>
                                                    <td>{this.renderInput(item, index)}
                                                    </td>
                                                    <td>
                                                        <MinusCircleOutlined className="delete" onClick={(e) => {
                                                            this.props.OnInputChange?.([...this.props.inputs.filter((i, idx) => idx !== index)])
                                                        }}/>
                                                    </td>
                                                </tr>
                                            }
                                            return <tr key={index}>
                                                <td><span><Tooltip
                                                    title={item.desc}><InfoCircleOutlined/></Tooltip>{item.name}</span>
                                                </td>
                                                <td>{item.type}</td>
                                                <td> {this.renderInput(item, index)}
                                                </td>
                                                <td></td>
                                            </tr>
                                        })
                                    }
                                    </tbody>


                                </table>
                                {
                                    this.props.editable &&
                                    <Button className={"add-btn"} size={"small"} type="primary" icon={<PlusOutlined/>}
                                            onClick={() => {
                                                this.props.OnInputChange?.([...this.props.inputs, {
                                                    name: 'new_input',
                                                    type: 'string',
                                                    value: ''
                                                }])
                                            }}>新增</Button>
                                }
                            </>
                        }]
                    }
                />

                <Collapse
                    className={"flow-item-body flow-item-output"}
                    size="small"
                    bordered={false}
                    items={[{
                        key: '1',
                        label: '输出',
                        children: <>
                            <table className='detail-table'>
                                <tbody>
                                <tr key={0}>
                                    <td className='tdTitle' style={{width: '50%'}}>变量名</td>
                                    <td className='tdTitle' style={{width: '40%'}}>变量类型</td>
                                    <td className='tdTitle' style={{width: '10%'}}></td>
                                </tr>
                                {
                                    this.props.outputs.map((item, index) => {
                                        if (this.props.editable) {
                                            return <tr key={index}>
                                                <td><Input size={"small"} value={item.name} onChange={(e) => {
                                                    item.name = e.target.value
                                                    this.setState({})
                                                    this.props.OnOutputChange?.(this.props.outputs)
                                                }} onClick={(e) => {
                                                    // @ts-ignore
                                                    e.target.focus()
                                                    e.stopPropagation()
                                                }}/></td>
                                                <td><Select size={"small"} popupMatchSelectWidth={120} value={item.type}
                                                            onChange={(e) => {
                                                                item.type = e
                                                                this.props.OnOutputChange?.(this.props.outputs)
                                                            }}>
                                                    {Object.keys(Types).map((type) => {
                                                        return <Select.Option value={type}
                                                                              key={type}>{type}</Select.Option>
                                                    })}
                                                </Select></td>
                                                <td>
                                                    <MinusCircleOutlined className="delete" onClick={(e) => {
                                                        this.props.OnOutputChange?.([...this.props.outputs.filter((i, idx) => idx !== index)])
                                                    }}/>
                                                </td>
                                            </tr>
                                        }
                                        return <tr key={index}>
                                            <td><span><Tooltip
                                                title={item.desc}><InfoCircleOutlined/></Tooltip>{item.name}</span></td>
                                            <td>{item.type}</td>
                                            <td></td>
                                        </tr>
                                    })
                                }
                                </tbody>
                            </table>
                            {
                                this.props.editable && <Button className={"add-btn"}
                                                               size={"small"} type="primary" icon={<PlusOutlined/>}
                                                               onClick={() => {
                                                                   this.props.OnOutputChange?.([...this.props.outputs, {
                                                                       name: 'new_output',
                                                                       type: 'string',
                                                                       value: ''
                                                                   }])
                                                               }}
                                >新增</Button>
                            }
                        </>
                    }]}
                />
            </div>
        )
    }
}
